#include "../logs/log.h"
////以时间来对文件滚动切换的日志落地模块
//时间段进行滚动
//实现思想:time(nullptr) % gap  以当前系统时间，取模时间大小，可以得到当前时间段是第几个时间段
enum class TimeGap{
    GAP_SECOND,
    GAP_MINUTE,
    GAP_HOUR,
    GAP_DAY
  };
  
  
  class RollByTimeSink : public mylog::LogSink{
       public:
         RollByTimeSink(const std::string &basename, TimeGap gaptype):_basename(basename)
      {
        switch(gaptype){
          case TimeGap::GAP_SECOND: _gap_size = 1;          break;
          case TimeGap::GAP_MINUTE: _gap_size = 60;         break;
          case TimeGap::GAP_HOUR: _gap_size = 3600;         break;
          case TimeGap::GAP_DAY: _gap_size = 3600 * 24;     break;
        } 
           //假如为1，取模会导致gap为0，要另作处理
           _cur_gap = _gap_size == 1 ? mylog::Util::Date::getTime() : mylog::Util::Date::getTime() % _gap_size;
           std::string filename = createFile(); //创建对应的文件名
           mylog::Util::File::CreateDirectory(mylog::Util::File::Path(filename));
           _ofs.open(filename, std::ios::binary | std::ios::app);
           assert(_ofs.is_open());
      }
         //将日志消息写到文件中
         void log(const char *data, size_t len){
           time_t cur = mylog::Util::Date::getTime();
           if((cur % _gap_size) != _cur_gap){
             _ofs.close();  //关闭源文件
             std::string filename = createFile();
             _ofs.open(filename, std::ios::binary | std::ios::app);
             assert(_ofs.is_open());
           }
           _ofs.write((const char*)data, len);
           assert(_ofs.good());
         }
       private:
         //判断当前文件是否满，然后创建新的文件
         std::string createFile(){
           //获取系统时间，以时间来构造文件
           time_t t = mylog::Util::Date::getTime();
           struct tm lt;
           localtime_r(&t, &lt);
           std::stringstream filename;
           filename << _basename;
           filename << lt.tm_year + 1900;
           filename << lt.tm_mon + 1;
           filename << lt.tm_mday;
           filename << lt.tm_hour;
           filename << lt.tm_min;
           filename << lt.tm_sec;
           filename << "-";
           filename << ".log";
           return filename.str();
         }
       private:
         std::string _basename;
         std::ofstream _ofs;
         size_t _gap_size;  //时间间隔
         size_t _cur_gap;   //当前时间段
  };

int main()
{  
   std::unique_ptr<mylog::LoggerBuilder> builder(new mylog::GlobalLoggerBuilder());
   builder->BuildLoggerName("async_logger");
   builder->BuildLoggerType(mylog::LoggerType::Async_logger);
   //builder->BuildLooperNotSafe();
   builder->BuildFormatter("[%c][%f:%l][%p]%T%m%n");
   builder->BuildLoggerLevel(mylog::LogLevel::value::WARN);
   builder->BuildSink<RollByTimeSink>("./logfile/roll-async-by-time", TimeGap::GAP_SECOND);
   mylog::logger::ptr logger = builder->build();
   size_t cur = mylog::Util::Date::getTime();
   while(mylog::Util::Date::getTime() < cur + 5){
    logger->fatal("%s","这是一条测试日志");
    usleep(1000);
   }
   
   return 0;
}
